//
//  NSString+Additions.m
//  Additions
//
//  Created by Johnil on 13-6-15.
//  Copyright (c) 2013年 Johnil. All rights reserved.
//

#import "NSString+Additions.h"
#import <CoreText/CoreText.h>
#import "M80AttributedLabelAttachment.h"

@implementation NSString (Additions)

#pragma mark - java api

- (NSUInteger) compareTo: (NSString*) comp {
    NSComparisonResult result = [self compare:comp];
    if (result == NSOrderedSame) {
        return 0;
    }
    return result == NSOrderedAscending ? -1 : 1;
}

- (NSUInteger) compareToIgnoreCase: (NSString*) comp {
    return [[self lowercaseString] compareTo:[comp lowercaseString]];
}

- (bool) contains: (NSString*) substring {
    NSRange range = [self rangeOfString:substring];
    return range.location != NSNotFound;
}

- (bool) endsWith: (NSString*) substring {
    NSRange range = [self rangeOfString:substring];
    return range.location == [self length] - [substring length];
}

- (bool) startsWith: (NSString*) substring {
    NSRange range = [self rangeOfString:substring];
    return range.location == 0;
}

- (NSUInteger) indexOf: (NSString*) substring {
    NSRange range = [self rangeOfString:substring options:NSCaseInsensitiveSearch];
    return range.location == NSNotFound ? -1 : range.location;
}

- (NSUInteger) indexOf:(NSString *)substring startingFrom: (NSUInteger) index {
    NSString* test = [self substringFromIndex:index];
    return index+[test indexOf:substring];
}

- (NSUInteger) lastIndexOf: (NSString*) substring {
    NSRange range = [self rangeOfString:substring options:NSBackwardsSearch];
    return range.location == NSNotFound ? -1 : range.location;
}

- (NSUInteger) lastIndexOf:(NSString *)substring startingFrom: (NSUInteger) index {
    NSString* test = [self substringFromIndex:index];
    return [test lastIndexOf:substring];
}

- (NSString*) substringFromIndex:(NSUInteger)from toIndex: (NSUInteger) to {
    NSRange range;
    range.location = from;
    range.length = to - from;
    return [self substringWithRange: range];
}

- (NSString*) trim {
    
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSArray*) split: (NSString*) token {
    return [self split:token limit:0];
}

- (NSArray*) split: (NSString*) token limit: (NSUInteger) maxResults {
    NSMutableArray* result = [NSMutableArray arrayWithCapacity: 8];
    NSString* buffer = self;
    while ([buffer contains:token]) {
        if (maxResults > 0 && [result count] == maxResults - 1) {
            break;
        }
        NSUInteger matchIndex = [buffer indexOf:token];
        NSString* nextPart = [buffer substringFromIndex:0 toIndex:matchIndex];
        buffer = [buffer substringFromIndex:matchIndex + [token length]];
        [result addObject:nextPart];
    }
    if ([buffer length] > 0) {
        [result addObject:buffer];
    }
    
    return result;
}

- (BOOL)isEmpty
{
    return (self == nil) || ([self isEqualToString:@""]) || (NSNull *)self == [NSNull null];
}

- (NSString*) replace: (NSString*) target withString: (NSString*) replacement {
    return [self stringByReplacingOccurrencesOfString:target withString:replacement];
}

- (CGSize)sizeWithConstrainedToWidth:(float)width fromFont:(UIFont *)font1 lineSpace:(float)lineSpace{
    return [self sizeWithConstrainedToSize:CGSizeMake(width, CGFLOAT_MAX) fromFont:font1 lineSpace:lineSpace];
}

- (NSInteger)numberOfLinesWithConstrainedToWidth:(float)width fromFont:(UIFont *)font1 lineSpace:(float)lineSpace {
    CGFloat minimumLineHeight = font1.pointSize,maximumLineHeight = minimumLineHeight, linespace = lineSpace;
    CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)font1.fontName,font1.pointSize,NULL);
    CTLineBreakMode lineBreakMode = kCTLineBreakByWordWrapping;
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, CGRectMake(0, 0, width, CGFLOAT_MAX));
    CTTextAlignment alignment = kCTLeftTextAlignment;
    CTParagraphStyleRef style = CTParagraphStyleCreate((CTParagraphStyleSetting[6]){
        {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment},
        {kCTParagraphStyleSpecifierMinimumLineHeight,sizeof(minimumLineHeight),&minimumLineHeight},
        {kCTParagraphStyleSpecifierMaximumLineHeight,sizeof(maximumLineHeight),&maximumLineHeight},
        {kCTParagraphStyleSpecifierMaximumLineSpacing, sizeof(linespace), &linespace},
        {kCTParagraphStyleSpecifierMinimumLineSpacing, sizeof(linespace), &linespace},
        {kCTParagraphStyleSpecifierLineBreakMode,sizeof(CTLineBreakMode),&lineBreakMode}
    },6);
    NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)font,(NSString*)kCTFontAttributeName,(__bridge id)style,(NSString*)kCTParagraphStyleAttributeName,nil];
    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:self attributes:attributes];
    CFAttributedStringRef attributedString = (__bridge CFAttributedStringRef)string;
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString);
    CTFrameRef frames = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, string.length), path, NULL);
    CFArrayRef lines = CTFrameGetLines(frames);
    CFRelease(framesetter);
    CFRelease(font);
    CFRelease(style);
    CFRelease(path);
    return CFArrayGetCount(lines);
    
}

- (CGSize)sizeWithConstrainedToSize:(CGSize)size fromFont:(UIFont *)font1 lineSpace:(float)lineSpace{
    CGFloat minimumLineHeight = font1.pointSize,maximumLineHeight = minimumLineHeight, linespace = lineSpace;
    CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)font1.fontName,font1.pointSize,NULL);
    CTLineBreakMode lineBreakMode = kCTLineBreakByWordWrapping;
    //Apply paragraph settings
    CTTextAlignment alignment = kCTLeftTextAlignment;
    CTParagraphStyleRef style = CTParagraphStyleCreate((CTParagraphStyleSetting[6]){
        {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment},
        {kCTParagraphStyleSpecifierMinimumLineHeight,sizeof(minimumLineHeight),&minimumLineHeight},
        {kCTParagraphStyleSpecifierMaximumLineHeight,sizeof(maximumLineHeight),&maximumLineHeight},
        {kCTParagraphStyleSpecifierMaximumLineSpacing, sizeof(linespace), &linespace},
        {kCTParagraphStyleSpecifierMinimumLineSpacing, sizeof(linespace), &linespace},
        {kCTParagraphStyleSpecifierLineBreakMode,sizeof(CTLineBreakMode),&lineBreakMode}
    },6);
    NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)font,(NSString*)kCTFontAttributeName,(__bridge id)style,(NSString*)kCTParagraphStyleAttributeName,nil];
    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:self attributes:attributes];
    //    [self clearEmoji:string start:0 font:font1];
    CFAttributedStringRef attributedString = (__bridge CFAttributedStringRef)string;
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString);
    CGSize result = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, [string length]), NULL, size, NULL);
    CFRelease(framesetter);
    CFRelease(font);
    CFRelease(style);
    string = nil;
    attributes = nil;
    return result;
}

- (void)drawInContext:(CGContextRef)context withPosition:(CGPoint)p andFont:(UIFont *)font andTextColor:(UIColor *)color andHeight:(float)height andWidth:(float)width{
    CGSize size = CGSizeMake(width, font.pointSize+10);
    CGContextSetTextMatrix(context,CGAffineTransformIdentity);
    CGContextTranslateCTM(context,0,height);
    CGContextScaleCTM(context,1.0,-1.0);
    
    //Determine default text color
    UIColor* textColor = color;
    //Set line height, font, color and break mode
    CTFontRef font1 = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize,NULL);
    //Apply paragraph settings
    CGFloat minimumLineHeight = font.pointSize,maximumLineHeight = minimumLineHeight+10, linespace = 5;
    CTLineBreakMode lineBreakMode = kCTLineBreakByTruncatingTail;
    CTTextAlignment alignment = kCTTextAlignmentCenter;
    //Apply paragraph settings
    CTParagraphStyleRef style = CTParagraphStyleCreate((CTParagraphStyleSetting[6]){
        {kCTParagraphStyleSpecifierAlignment, sizeof(alignment), &alignment},
        {kCTParagraphStyleSpecifierMinimumLineHeight,sizeof(minimumLineHeight),&minimumLineHeight},
        {kCTParagraphStyleSpecifierMaximumLineHeight,sizeof(maximumLineHeight),&maximumLineHeight},
        {kCTParagraphStyleSpecifierMaximumLineSpacing, sizeof(linespace), &linespace},
        {kCTParagraphStyleSpecifierMinimumLineSpacing, sizeof(linespace), &linespace},
        {kCTParagraphStyleSpecifierLineBreakMode,sizeof(CTLineBreakMode),&lineBreakMode}
    },6);
    
    NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)font1,(NSString*)kCTFontAttributeName,
                                textColor.CGColor,kCTForegroundColorAttributeName,
                                style,kCTParagraphStyleAttributeName,
                                nil];
    //Create path to work with a frame with applied margins
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path,NULL,CGRectMake(p.x, height-p.y-size.height,(size.width),(size.height)));
    
    //Create attributed string, with applied syntax highlighting
    NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:self attributes:attributes];
    CFAttributedStringRef attributedString = (__bridge CFAttributedStringRef)attributedStr;
    
    //Draw the frame
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString);
    CTFrameRef ctframe = CTFramesetterCreateFrame(framesetter, CFRangeMake(0,CFAttributedStringGetLength(attributedString)),path,NULL);
    CTFrameDraw(ctframe,context);
    CGPathRelease(path);
    CFRelease(font1);
    CFRelease(framesetter);
    CFRelease(ctframe);
    [[attributedStr mutableString] setString:@""];
    CGContextSetTextMatrix(context,CGAffineTransformIdentity);
    CGContextTranslateCTM(context,0, height);
    CGContextScaleCTM(context,1.0,-1.0);
}

- (void)drawInContext:(CGContextRef)context withPosition:(CGPoint)p andFont:(UIFont *)font andTextColor:(UIColor *)color andHeight:(float)height{
    [self drawInContext:context withPosition:p andFont:font andTextColor:color andHeight:height andWidth:CGFLOAT_MAX];
}

- (CGSize)sizeWithConstrainedToWidth:(float)width fromFont:(UIFont *)font1 lineSpace:(float)lineSpace numberOfLines:(int)numberOfLines
{
    CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)font1.fontName,font1.pointSize,NULL);
    NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)font,(NSString*)kCTFontAttributeName,nil];
    NSMutableAttributedString *drawString = [[NSMutableAttributedString alloc] initWithString:self attributes:attributes];
    
    //如果LineBreakMode为TranncateTail,那么默认排版模式改成kCTLineBreakByCharWrapping,使得尽可能地显示所有文字
    CTLineBreakMode lineBreakMode = kCTLineBreakByTruncatingTail;
    if (lineBreakMode == kCTLineBreakByTruncatingTail)
    {
        lineBreakMode = numberOfLines == 1 ? kCTLineBreakByCharWrapping : kCTLineBreakByWordWrapping;
    }
    CGFloat _fontLineHeight = font1.lineHeight;  //使用全局fontHeight作为最小lineHeight
    CTTextAlignment _textAlignment = kCTLeftTextAlignment;
    CGFloat _paragraphSpacing = 0.0f;
    CTParagraphStyleSetting settings[] =
    {
        {kCTParagraphStyleSpecifierAlignment,sizeof(_textAlignment),&_textAlignment},
        {kCTParagraphStyleSpecifierLineBreakMode,sizeof(lineBreakMode),&lineBreakMode},
        {kCTParagraphStyleSpecifierMaximumLineSpacing,sizeof(lineSpace),&lineSpace},
        {kCTParagraphStyleSpecifierMinimumLineSpacing,sizeof(lineSpace),&lineSpace},
        {kCTParagraphStyleSpecifierParagraphSpacing,sizeof(_paragraphSpacing),&_paragraphSpacing},
        {kCTParagraphStyleSpecifierMinimumLineHeight,sizeof(_fontLineHeight),&_fontLineHeight},
    };
    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings,sizeof(settings) / sizeof(settings[0]));
    [drawString addAttribute:(id)kCTParagraphStyleAttributeName
                       value:(__bridge id)paragraphStyle
                       range:NSMakeRange(0, [drawString length])];
    CFRelease(paragraphStyle);
    if (drawString == nil)
    {
        return CGSizeZero;
    }
    CFAttributedStringRef attributedStringRef = (__bridge CFAttributedStringRef)drawString;
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attributedStringRef);
    CFRange range = CFRangeMake(0, 0);
    if (numberOfLines > 0 && framesetter)
    {
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddRect(path, NULL, CGRectMake(0, 0, width, CGFLOAT_MAX));
        CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
        CFArrayRef lines = CTFrameGetLines(frame);
        
        if (nil != lines && CFArrayGetCount(lines) > 0)
        {
            NSInteger lastVisibleLineIndex = MIN(numberOfLines, CFArrayGetCount(lines)) - 1;
            CTLineRef lastVisibleLine = CFArrayGetValueAtIndex(lines, lastVisibleLineIndex);
            
            CFRange rangeToLayout = CTLineGetStringRange(lastVisibleLine);
            range = CFRangeMake(0, rangeToLayout.location + rangeToLayout.length);
        }
        CFRelease(frame);
        CFRelease(path);
        
    }
    
    CFRange fitCFRange = CFRangeMake(0, 0);
    CGSize newSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, range, NULL, CGSizeMake(width, CGFLOAT_MAX), &fitCFRange);
    if (framesetter)
    {
        CFRelease(framesetter);
    }

    //hack:
    //1.需要加上额外的一部分size,有些情况下计算出来的像素点并不是那么精准
    //2.ios7的CTFramesetterSuggestFrameSizeWithConstraints方法比较残,需要多加一部分height
    //3.ios7多行中如果首行带有很多空格，会导致返回的suggestionWidth远小于真是width,那么多行情况下就是用传入的width
    if ([[[UIDevice currentDevice] systemVersion] doubleValue] >= 7.0)
    {
        if (newSize.height < CTFontGetSize(font) * 2)   //单行
        {
            CFRelease(font);
            return CGSizeMake(ceilf(newSize.width) + 2.0, ceilf(newSize.height) + 4.0);
        }
        else
        {
            CFRelease(font);
            return CGSizeMake(width, ceilf(newSize.height) + 4.0);
        }
    }
    else
    {
        CFRelease(font);
        return CGSizeMake(ceilf(newSize.width) + 2.0, ceilf(newSize.height) + 2.0);
    }
    
}


- (NSMutableDictionary *)sizeWithConstrainedToWidth:(float)width fromFont:(UIFont *)font1 lineSpace:(float)lineSpace numberOfLines:(int)numberOfLines andAttachment:(M80AttributedLabelAttachment *)attachment
{
    NSMutableDictionary *data = [NSMutableDictionary dictionary];
    CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)font1.fontName,font1.pointSize,NULL);
    
    attachment.fontAscent                   = CTFontGetAscent(font);
    attachment.fontDescent                  = CTFontGetDescent(font);
    unichar objectReplacementChar           = 0xFFFC;
    NSString *objectReplacementString       = [NSString stringWithCharacters:&objectReplacementChar length:1];
    NSMutableAttributedString *attachText   = [[NSMutableAttributedString alloc]initWithString:objectReplacementString];
    
    CTRunDelegateCallbacks callbacks;
    callbacks.version       = kCTRunDelegateVersion1;
    callbacks.getAscent     = ascentCallback;
    callbacks.getDescent    = descentCallback;
    callbacks.getWidth      = widthCallback;
    callbacks.dealloc       = deallocCallback;
    
    CTRunDelegateRef delegate = CTRunDelegateCreate(&callbacks, (void *)attachment);
    NSDictionary *attr = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)delegate,kCTRunDelegateAttributeName, nil];
    [attachText setAttributes:attr range:NSMakeRange(0, 1)];
    CFRelease(delegate);
    
    NSMutableAttributedString *drawString = attachText;
    
    NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)font,(NSString*)kCTFontAttributeName,nil];
    //NSMutableAttributedString *drawString = [[NSMutableAttributedString alloc] initWithString:self attributes:attributes];
    [drawString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:self attributes:attributes]];
    
    //如果LineBreakMode为TranncateTail,那么默认排版模式改成kCTLineBreakByCharWrapping,使得尽可能地显示所有文字
    CTLineBreakMode lineBreakMode = kCTLineBreakByTruncatingTail;
    if (lineBreakMode == kCTLineBreakByTruncatingTail)
    {
        lineBreakMode = numberOfLines == 1 ? kCTLineBreakByCharWrapping : kCTLineBreakByWordWrapping;
    }
    CGFloat _fontLineHeight = font1.lineHeight;  //使用全局fontHeight作为最小lineHeight
    CTTextAlignment _textAlignment = kCTLeftTextAlignment;
    CGFloat _paragraphSpacing = 0.0f;
    CTParagraphStyleSetting settings[] =
    {
        {kCTParagraphStyleSpecifierAlignment,sizeof(_textAlignment),&_textAlignment},
        {kCTParagraphStyleSpecifierLineBreakMode,sizeof(lineBreakMode),&lineBreakMode},
        {kCTParagraphStyleSpecifierMaximumLineSpacing,sizeof(lineSpace),&lineSpace},
        {kCTParagraphStyleSpecifierMinimumLineSpacing,sizeof(lineSpace),&lineSpace},
        {kCTParagraphStyleSpecifierParagraphSpacing,sizeof(_paragraphSpacing),&_paragraphSpacing},
        {kCTParagraphStyleSpecifierMinimumLineHeight,sizeof(_fontLineHeight),&_fontLineHeight},
    };
    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(settings,sizeof(settings) / sizeof(settings[0]));
    [drawString addAttribute:(id)kCTParagraphStyleAttributeName
                       value:(__bridge id)paragraphStyle
                       range:NSMakeRange(0, [drawString length])];
    CFRelease(paragraphStyle);
    
    //data[@"attributeString"] = drawString;
    if (drawString == nil)
    {
        return data;
    }
    CFAttributedStringRef attributedStringRef = (__bridge CFAttributedStringRef)drawString;
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attributedStringRef);
    CFRange range = CFRangeMake(0, 0);
    if (numberOfLines > 0 && framesetter)
    {
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddRect(path, NULL, CGRectMake(0, 0, width, CGFLOAT_MAX));
        CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
        CFArrayRef lines = CTFrameGetLines(frame);
        
        if (nil != lines && CFArrayGetCount(lines) > 0)
        {
            NSInteger lastVisibleLineIndex = MIN(numberOfLines, CFArrayGetCount(lines)) - 1;
            CTLineRef lastVisibleLine = CFArrayGetValueAtIndex(lines, lastVisibleLineIndex);
            
            CFRange rangeToLayout = CTLineGetStringRange(lastVisibleLine);
            range = CFRangeMake(0, rangeToLayout.location + rangeToLayout.length);
        }
        CFRelease(frame);
        CFRelease(path);
        
    }
    
    CFRange fitCFRange = CFRangeMake(0, 0);
    CGSize newSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, range, NULL, CGSizeMake(width, CGFLOAT_MAX), &fitCFRange);
    if (framesetter)
    {
        CFRelease(framesetter);
    }
    
    //hack:
    //1.需要加上额外的一部分size,有些情况下计算出来的像素点并不是那么精准
    //2.ios7的CTFramesetterSuggestFrameSizeWithConstraints方法比较残,需要多加一部分height
    //3.ios7多行中如果首行带有很多空格，会导致返回的suggestionWidth远小于真是width,那么多行情况下就是用传入的width
    if ([[[UIDevice currentDevice] systemVersion] doubleValue] >= 7.0)
    {
        if (newSize.height < CTFontGetSize(font) * 2)   //单行
        {
            CFRelease(font);
            data[@"size"] = [NSValue valueWithCGSize:CGSizeMake(ceilf(newSize.width) + 2.0, ceilf(newSize.height))];
        }
        else
        {
            CFRelease(font);
            data[@"size"] = [NSValue valueWithCGSize:CGSizeMake(width, ceilf(newSize.height))];
        }
    }
    else
    {
        CFRelease(font);
        data[@"size"] = [NSValue valueWithCGSize:CGSizeMake(ceilf(newSize.width) + 2.0, ceilf(newSize.height) + 2.0)];
    }
    return data;
}


- (NSString*) EncodeEmojiAndEnter
{
    //NSString *content = [self stringByReplacingOccurrencesOfString:@"<br/>" withString:@"\n"];
    NSString *content = self;
    NSArray *unicodes = @[@"128513",@"128514",@"128515",@"128516",@"128517",@"128518",@"128521",@"128522",@"128523",@"128524",@"128525",@"128527",@"128530",@"128531",@"128532",@"128534",@"128536",@"128538",@"128540",@"128541",@"128542",@"128544",@"128545",@"128546",@"128547",@"128548",@"128549",@"128552",@"128553",@"128554",@"128555",@"128557",@"128560",@"128561",@"128562",@"128563",@"128565",@"128567",@"128568",@"128569",@"128570",@"128571",@"128572",@"128573",@"128574",@"128575",@"128576",@"128581",@"128582",@"128583",@"128584",@"128585",@"128586",@"128587",@"128588",@"128589",@"128590",@"128591",@"9986",@"9989",@"9992",@"9993",@"9994",@"9995",@"9996",@"9999",@"10002",@"10004",@"10006",@"10024",@"10035",@"10036",@"10052",@"10055",@"10060",@"10062",@"10067",@"10068",@"10069",@"10071",@"10084",@"10133",@"10134",@"10135",@"10145",@"10160",@"128640",@"128643",@"128644",@"128645",@"128647",@"128649",@"128652",@"128655",@"128657",@"128658",@"128659",@"128661",@"128663",@"128665",@"128666",@"128674",@"128676",@"128677",@"128679",@"128680",@"128681",@"128682",@"128683",@"128684",@"128685",@"128690",@"128694",@"128697",@"128698",@"128699",@"128700",@"128701",@"128702",@"128704",@"9410",@"127344",@"127345",@"127358",@"127359",@"127374",@"127377",@"127378",@"127379",@"127380",@"127381",@"127382",@"127383",@"127384",@"127385",@"127386",@"127489",@"127490",@"127514",@"127535",@"127538",@"127539",@"127540",@"127541",@"127542",@"127543",@"127544",@"127545",@"127546",@"127568",@"127569",@"169",@"174",@"8252",@"8265",@"8482",@"8505",@"8596",@"8597",@"8598",@"8599",@"8600",@"8601",@"8617",@"8618",@"8986",@"8987",@"9193",@"9194",@"9195",@"9196",@"9200",@"9203",@"9642",@"9643",@"9654",@"9664",@"9723",@"9724",@"9725",@"9726",@"9728",@"9729",@"9742",@"9745",@"9748",@"9749",@"9757",@"9786",@"9800",@"9801",@"9802",@"9803",@"9804",@"9805",@"9806",@"9807",@"9808",@"9809",@"9810",@"9811",@"9824",@"9827",@"9829",@"9830",@"9832",@"9851",@"9855",@"9875",@"9888",@"9889",@"9898",@"9899",@"9917",@"9918",@"9924",@"9925",@"9934",@"9940",@"9962",@"9970",@"9971",@"9973",@"9978",@"9981",@"10548",@"10549",@"11013",@"11014",@"11015",@"11035",@"11036",@"11088",@"11093",@"12336",@"12349",@"12951",@"12953",@"126980",@"127183",@"127744",@"127745",@"127746",@"127747",@"127748",@"127749",@"127750",@"127751",@"127752",@"127753",@"127754",@"127755",@"127756",@"127759",@"127761",@"127763",@"127764",@"127765",@"127769",@"127771",@"127775",@"127776",@"127792",@"127793",@"127796",@"127797",@"127799",@"127800",@"127801",@"127802",@"127803",@"127804",@"127805",@"127806",@"127807",@"127808",@"127809",@"127810",@"127811",@"127812",@"127813",@"127814",@"127815",@"127816",@"127817",@"127818",@"127820",@"127821",@"127822",@"127823",@"127825",@"127826",@"127827",@"127828",@"127829",@"127830",@"127831",@"127832",@"127833",@"127834",@"127835",@"127836",@"127837",@"127838",@"127839",@"127840",@"127841",@"127842",@"127843",@"127844",@"127845",@"127846",@"127847",@"127848",@"127849",@"127850",@"127851",@"127852",@"127853",@"127854",@"127855",@"127856",@"127857",@"127858",@"127859",@"127860",@"127861",@"127862",@"127863",@"127864",@"127865",@"127866",@"127867",@"127872",@"127873",@"127874",@"127875",@"127876",@"127877",@"127878",@"127879",@"127880",@"127881",@"127882",@"127883",@"127884",@"127885",@"127886",@"127887",@"127888",@"127889",@"127890",@"127891",@"127904",@"127905",@"127906",@"127907",@"127908",@"127909",@"127910",@"127911",@"127912",@"127913",@"127914",@"127915",@"127916",@"127917",@"127918",@"127919",@"127920",@"127921",@"127922",@"127923",@"127924",@"127925",@"127926",@"127927",@"127928",@"127929",@"127930",@"127931",@"127932",@"127933",@"127934",@"127935",@"127936",@"127937",@"127938",@"127939",@"127940",@"127942",@"127944",@"127946",@"127968",@"127969",@"127970",@"127971",@"127973",@"127974",@"127975",@"127976",@"127977",@"127978",@"127979",@"127980",@"127981",@"127982",@"127983",@"127984",@"128012",@"128013",@"128014",@"128017",@"128018",@"128020",@"128023",@"128024",@"128025",@"128026",@"128027",@"128028",@"128029",@"128030",@"128031",@"128032",@"128033",@"128034",@"128035",@"128036",@"128037",@"128038",@"128039",@"128040",@"128041",@"128043",@"128044",@"128045",@"128046",@"128047",@"128048",@"128049",@"128050",@"128051",@"128052",@"128053",@"128054",@"128055",@"128056",@"128057",@"128058",@"128059",@"128060",@"128061",@"128062",@"128064",@"128066",@"128067",@"128068",@"128069",@"128070",@"128071",@"128072",@"128073",@"128074",@"128075",@"128076",@"128077",@"128078",@"128079",@"128080",@"128081",@"128082",@"128083",@"128084",@"128085",@"128086",@"128087",@"128088",@"128089",@"128090",@"128091",@"128092",@"128093",@"128094",@"128095",@"128096",@"128097",@"128098",@"128099",@"128100",@"128102",@"128103",@"128104",@"128105",@"128106",@"128107",@"128110",@"128111",@"128112",@"128113",@"128114",@"128115",@"128116",@"128117",@"128118",@"128119",@"128120",@"128121",@"128122",@"128123",@"128124",@"128125",@"128126",@"128127",@"128128",@"128129",@"128130",@"128131",@"128132",@"128133",@"128134",@"128135",@"128136",@"128137",@"128138",@"128139",@"128140",@"128141",@"128142",@"128143",@"128144",@"128145",@"128146",@"128147",@"128148",@"128149",@"128150",@"128151",@"128152",@"128153",@"128154",@"128155",@"128156",@"128157",@"128158",@"128159",@"128160",@"128161",@"128162",@"128163",@"128164",@"128165",@"128166",@"128167",@"128168",@"128169",@"128170",@"128171",@"128172",@"128174",@"128175",@"128176",@"128177",@"128178",@"128179",@"128180",@"128181",@"128184",@"128185",@"128186",@"128187",@"128188",@"128189",@"128190",@"128191",@"128192",@"128193",@"128194",@"128195",@"128196",@"128197",@"128198",@"128199",@"128200",@"128201",@"128202",@"128203",@"128204",@"128205",@"128206",@"128207",@"128208",@"128209",@"128210",@"128211",@"128212",@"128213",@"128214",@"128215",@"128216",@"128217",@"128218",@"128219",@"128220",@"128221",@"128222",@"128223",@"128224",@"128225",@"128226",@"128227",@"128228",@"128229",@"128230",@"128231",@"128232",@"128233",@"128234",@"128235",@"128238",@"128240",@"128241",@"128242",@"128243",@"128244",@"128246",@"128247",@"128249",@"128250",@"128251",@"128252",@"128259",@"128266",@"128267",@"128268",@"128269",@"128270",@"128271",@"128272",@"128273",@"128274",@"128275",@"128276",@"128278",@"128279",@"128280",@"128281",@"128282",@"128283",@"128284",@"128285",@"128286",@"128287",@"128288",@"128289",@"128290",@"128291",@"128292",@"128293",@"128294",@"128295",@"128296",@"128297",@"128298",@"128299",@"128302",@"128303",@"128304",@"128305",@"128306",@"128307",@"128308",@"128309",@"128310",@"128311",@"128312",@"128313",@"128314",@"128315",@"128316",@"128317",@"128336",@"128337",@"128338",@"128339",@"128340",@"128341",@"128342",@"128343",@"128344",@"128345",@"128346",@"128347",@"128507",@"128508",@"128509",@"128510",@"128511",@"128512",@"128519",@"128520",@"128526",@"128528",@"128529",@"128533",@"128535",@"128537",@"128539",@"128543",@"128550",@"128551",@"128556",@"128558",@"128559",@"128564",@"128566",@"128641",@"128642",@"128646",@"128648",@"128650",@"128653",@"128654",@"128656",@"128660",@"128662",@"128664",@"128667",@"128668",@"128669",@"128670",@"128671",@"128672",@"128673",@"128675",@"128678",@"128686",@"128687",@"128688",@"128689",@"128691",@"128692",@"128693",@"128695",@"128696",@"128703",@"128705",@"128706",@"128707",@"128708",@"128709",@"127757",@"127758",@"127760",@"127762",@"127766",@"127767",@"127768",@"127770",@"127772",@"127773",@"127774",@"127794",@"127795",@"127819",@"127824",@"127868",@"127943",@"127945",@"127972",@"128000",@"128001",@"128002",@"128003",@"128004",@"128005",@"128006",@"128007",@"128008",@"128009",@"128010",@"128011",@"128015",@"128016",@"128019",@"128021",@"128022",@"128042",@"128101",@"128108",@"128109",@"128173",@"128182",@"128183",@"128236",@"128237",@"128239",@"128245",@"128256",@"128257",@"128258",@"128260",@"128261",@"128262",@"128263",@"128265",@"128277",@"128300",@"128301",@"128348",@"128349",@"128350",@"128351",@"128352",@"128353",@"128354",@"128355",@"128356",@"128357",@"128358",@"128359",];
    NSArray *emojis = @[@"😁",@"😂",@"😃",@"😄",@"😅",@"😆",@"😉",@"😊",@"😋",@"😌",@"😍",@"😏",@"😒",@"😓",@"😔",@"😖",@"😘",@"😚",@"😜",@"😝",@"😞",@"😠",@"😡",@"😢",@"😣",@"😤",@"😥",@"😨",@"😩",@"😪",@"😫",@"😭",@"😰",@"😱",@"😲",@"😳",@"😵",@"😷",@"😸",@"😹",@"😺",@"😻",@"😼",@"😽",@"😾",@"😿",@"🙀",@"🙅",@"🙆",@"🙇",@"🙈",@"🙉",@"🙊",@"🙋",@"🙌",@"🙍",@"🙎",@"🙏",@"✂",@"✅",@"✈",@"✉",@"✊",@"✋",@"✌",@"✏",@"✒",@"✔",@"✖",@"✨",@"✳",@"✴",@"❄",@"❇",@"❌",@"❎",@"❓",@"❔",@"❕",@"❗",@"❤",@"➕",@"➖",@"➗",@"➡",@"➰",@"🚀",@"🚃",@"🚄",@"🚅",@"🚇",@"🚉",@"🚌",@"🚏",@"🚑",@"🚒",@"🚓",@"🚕",@"🚗",@"🚙",@"🚚",@"🚢",@"🚤",@"🚥",@"🚧",@"🚨",@"🚩",@"🚪",@"🚫",@"🚬",@"🚭",@"🚲",@"🚶",@"🚹",@"🚺",@"🚻",@"🚼",@"🚽",@"🚾",@"🛀",@"Ⓜ",@"🅰",@"🅱",@"🅾",@"🅿",@"🆎",@"🆑",@"🆒",@"🆓",@"🆔",@"🆕",@"🆖",@"🆗",@"🆘",@"🆙",@"🆚",@"🈁",@"🈂",@"🈚",@"🈯",@"🈲",@"🈳",@"🈴",@"🈵",@"🈶",@"🈷",@"🈸",@"🈹",@"🈺",@"🉐",@"🉑",@"©",@"®",@"‼",@"⁉",@"™",@"ℹ",@"↔",@"↕",@"↖",@"↗",@"↘",@"↙",@"↩",@"↪",@"⌚",@"⌛",@"⏩",@"⏪",@"⏫",@"⏬",@"⏰",@"⏳",@"▪",@"▫",@"▶",@"◀",@"◻",@"◼",@"◽",@"◾",@"☀",@"☁",@"☎",@"☑",@"☔",@"☕",@"☝",@"☺",@"♈",@"♉",@"♊",@"♋",@"♌",@"♍",@"♎",@"♏",@"♐",@"♑",@"♒",@"♓",@"♠",@"♣",@"♥",@"♦",@"♨",@"♻",@"♿",@"⚓",@"⚠",@"⚡",@"⚪",@"⚫",@"⚽",@"⚾",@"⛄",@"⛅",@"⛎",@"⛔",@"⛪",@"⛲",@"⛳",@"⛵",@"⛺",@"⛽",@"⤴",@"⤵",@"⬅",@"⬆",@"⬇",@"⬛",@"⬜",@"⭐",@"⭕",@"〰",@"〽",@"㊗",@"㊙",@"🀄",@"🃏",@"🌀",@"🌁",@"🌂",@"🌃",@"🌄",@"🌅",@"🌆",@"🌇",@"🌈",@"🌉",@"🌊",@"🌋",@"🌌",@"🌏",@"🌑",@"🌓",@"🌔",@"🌕",@"🌙",@"🌛",@"🌟",@"🌠",@"🌰",@"🌱",@"🌴",@"🌵",@"🌷",@"🌸",@"🌹",@"🌺",@"🌻",@"🌼",@"🌽",@"🌾",@"🌿",@"🍀",@"🍁",@"🍂",@"🍃",@"🍄",@"🍅",@"🍆",@"🍇",@"🍈",@"🍉",@"🍊",@"🍌",@"🍍",@"🍎",@"🍏",@"🍑",@"🍒",@"🍓",@"🍔",@"🍕",@"🍖",@"🍗",@"🍘",@"🍙",@"🍚",@"🍛",@"🍜",@"🍝",@"🍞",@"🍟",@"🍠",@"🍡",@"🍢",@"🍣",@"🍤",@"🍥",@"🍦",@"🍧",@"🍨",@"🍩",@"🍪",@"🍫",@"🍬",@"🍭",@"🍮",@"🍯",@"🍰",@"🍱",@"🍲",@"🍳",@"🍴",@"🍵",@"🍶",@"🍷",@"🍸",@"🍹",@"🍺",@"🍻",@"🎀",@"🎁",@"🎂",@"🎃",@"🎄",@"🎅",@"🎆",@"🎇",@"🎈",@"🎉",@"🎊",@"🎋",@"🎌",@"🎍",@"🎎",@"🎏",@"🎐",@"🎑",@"🎒",@"🎓",@"🎠",@"🎡",@"🎢",@"🎣",@"🎤",@"🎥",@"🎦",@"🎧",@"🎨",@"🎩",@"🎪",@"🎫",@"🎬",@"🎭",@"🎮",@"🎯",@"🎰",@"🎱",@"🎲",@"🎳",@"🎴",@"🎵",@"🎶",@"🎷",@"🎸",@"🎹",@"🎺",@"🎻",@"🎼",@"🎽",@"🎾",@"🎿",@"🏀",@"🏁",@"🏂",@"🏃",@"🏄",@"🏆",@"🏈",@"🏊",@"🏠",@"🏡",@"🏢",@"🏣",@"🏥",@"🏦",@"🏧",@"🏨",@"🏩",@"🏪",@"🏫",@"🏬",@"🏭",@"🏮",@"🏯",@"🏰",@"🐌",@"🐍",@"🐎",@"🐑",@"🐒",@"🐔",@"🐗",@"🐘",@"🐙",@"🐚",@"🐛",@"🐜",@"🐝",@"🐞",@"🐟",@"🐠",@"🐡",@"🐢",@"🐣",@"🐤",@"🐥",@"🐦",@"🐧",@"🐨",@"🐩",@"🐫",@"🐬",@"🐭",@"🐮",@"🐯",@"🐰",@"🐱",@"🐲",@"🐳",@"🐴",@"🐵",@"🐶",@"🐷",@"🐸",@"🐹",@"🐺",@"🐻",@"🐼",@"🐽",@"🐾",@"👀",@"👂",@"👃",@"👄",@"👅",@"👆",@"👇",@"👈",@"👉",@"👊",@"👋",@"👌",@"👍",@"👎",@"👏",@"👐",@"👑",@"👒",@"👓",@"👔",@"👕",@"👖",@"👗",@"👘",@"👙",@"👚",@"👛",@"👜",@"👝",@"👞",@"👟",@"👠",@"👡",@"👢",@"👣",@"👤",@"👦",@"👧",@"👨",@"👩",@"👪",@"👫",@"👮",@"👯",@"👰",@"👱",@"👲",@"👳",@"👴",@"👵",@"👶",@"👷",@"👸",@"👹",@"👺",@"👻",@"👼",@"👽",@"👾",@"👿",@"💀",@"💁",@"💂",@"💃",@"💄",@"💅",@"💆",@"💇",@"💈",@"💉",@"💊",@"💋",@"💌",@"💍",@"💎",@"💏",@"💐",@"💑",@"💒",@"💓",@"💔",@"💕",@"💖",@"💗",@"💘",@"💙",@"💚",@"💛",@"💜",@"💝",@"💞",@"💟",@"💠",@"💡",@"💢",@"💣",@"💤",@"💥",@"💦",@"💧",@"💨",@"💩",@"💪",@"💫",@"💬",@"💮",@"💯",@"💰",@"💱",@"💲",@"💳",@"💴",@"💵",@"💸",@"💹",@"💺",@"💻",@"💼",@"💽",@"💾",@"💿",@"📀",@"📁",@"📂",@"📃",@"📄",@"📅",@"📆",@"📇",@"📈",@"📉",@"📊",@"📋",@"📌",@"📍",@"📎",@"📏",@"📐",@"📑",@"📒",@"📓",@"📔",@"📕",@"📖",@"📗",@"📘",@"📙",@"📚",@"📛",@"📜",@"📝",@"📞",@"📟",@"📠",@"📡",@"📢",@"📣",@"📤",@"📥",@"📦",@"📧",@"📨",@"📩",@"📪",@"📫",@"📮",@"📰",@"📱",@"📲",@"📳",@"📴",@"📶",@"📷",@"📹",@"📺",@"📻",@"📼",@"🔃",@"🔊",@"🔋",@"🔌",@"🔍",@"🔎",@"🔏",@"🔐",@"🔑",@"🔒",@"🔓",@"🔔",@"🔖",@"🔗",@"🔘",@"🔙",@"🔚",@"🔛",@"🔜",@"🔝",@"🔞",@"🔟",@"🔠",@"🔡",@"🔢",@"🔣",@"🔤",@"🔥",@"🔦",@"🔧",@"🔨",@"🔩",@"🔪",@"🔫",@"🔮",@"🔯",@"🔰",@"🔱",@"🔲",@"🔳",@"🔴",@"🔵",@"🔶",@"🔷",@"🔸",@"🔹",@"🔺",@"🔻",@"🔼",@"🔽",@"🕐",@"🕑",@"🕒",@"🕓",@"🕔",@"🕕",@"🕖",@"🕗",@"🕘",@"🕙",@"🕚",@"🕛",@"🗻",@"🗼",@"🗽",@"🗾",@"🗿",@"😀",@"😇",@"😈",@"😎",@"😐",@"😑",@"😕",@"😗",@"😙",@"😛",@"😟",@"😦",@"😧",@"😬",@"😮",@"😯",@"😴",@"😶",@"🚁",@"🚂",@"🚆",@"🚈",@"🚊",@"🚍",@"🚎",@"🚐",@"🚔",@"🚖",@"🚘",@"🚛",@"🚜",@"🚝",@"🚞",@"🚟",@"🚠",@"🚡",@"🚣",@"🚦",@"🚮",@"🚯",@"🚰",@"🚱",@"🚳",@"🚴",@"🚵",@"🚷",@"🚸",@"🚿",@"🛁",@"🛂",@"🛃",@"🛄",@"🛅",@"🌍",@"🌎",@"🌐",@"🌒",@"🌖",@"🌗",@"🌘",@"🌚",@"🌜",@"🌝",@"🌞",@"🌲",@"🌳",@"🍋",@"🍐",@"🍼",@"🏇",@"🏉",@"🏤",@"🐀",@"🐁",@"🐂",@"🐃",@"🐄",@"🐅",@"🐆",@"🐇",@"🐈",@"🐉",@"🐊",@"🐋",@"🐏",@"🐐",@"🐓",@"🐕",@"🐖",@"🐪",@"👥",@"👬",@"👭",@"💭",@"💶",@"💷",@"📬",@"📭",@"📯",@"📵",@"🔀",@"🔁",@"🔂",@"🔄",@"🔅",@"🔆",@"🔇",@"🔉",@"🔕",@"🔬",@"🔭",@"🕜",@"🕝",@"🕞",@"🕟",@"🕠",@"🕡",@"🕢",@"🕣",@"🕤",@"🕥",@"🕦",@"🕧",];
    for (int i=0;i<unicodes.count;i++) {
        if ([content rangeOfString:[NSString stringWithFormat:@"<span dir=\"ltr\">&#%@;</span>", unicodes[i]]].length > 0) {
            content = [content stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"<span dir=\"ltr\">&#%@;</span>", unicodes[i]] withString:emojis[i]];
        }
    }
    return content;
}

@end
